package cn.tedu;

import cn.tedu.common.vo.JsonResult;
import cn.tedu.pojo.dto.ItemAddDTO;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.annotation.RequestBody;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 演示mvc
 * json和form解析
 *
 * @author Kiven
 */
public class JsonFormPare {


    public static <T> T parseAndPackage(String str, Class<T> resultCls) throws Exception{
        // 传递过来的参数 保存到map中
        Map<String, Object> map = new HashMap<>();
        boolean isJson = str.startsWith("{");
        // 判断是json还是form
        if (isJson) {
            // json " {name:杯子,price:123} " -> "name:杯子,price:123"
            str = str.substring(1, str.length() - 1);
            // "name:杯子,price:123" -> ["name:杯子","price:123"]
            String[] params = str.split(",");
            // 把参数放到map中
            for (String param : params) {
                String[] kv = param.split(":");
                map.put(kv[0], kv[1]);
            }
        } else {
            // form
            str = str.substring(1, str.length());
            String[] split = str.split("&");
            for (String param : split) {
                String[] kv = param.split("=");
                map.put(kv[0], kv[1]);
            }
        }

        System.out.println(map);
        // 把map中的数据封装到对象中，并执行该方法

        // HandlerMapping里面存储的路径， 方法是一个map类是一个map
        // 模拟从mvc的handlerMapping取出来controller的完全限定名，并执行该匹配的getMapping的方法
        Class<?> cls = Class.forName("cn.tedu.controller.ItemController");
        // 模拟我从mvc拿到对应执行的方法名了
        Method addItem = cls.getDeclaredMethod("addItem", ItemAddDTO.class);
        Class<?>[] parameterTypes = addItem.getParameterTypes();

        // 如果有加requestBody注解但是是form格式 就报错
        boolean hasRequestBody = false;
        Annotation[][] annotation = addItem.getParameterAnnotations();
        for (Annotation[] annotations : annotation) {
            for (Annotation annotation1 : annotations) {
                if(annotation1.annotationType() == RequestBody.class){
                    hasRequestBody = true;
                }
            }
        }
        if(isJson && !hasRequestBody){
            return (T) addItem.invoke(cls.newInstance(), parameterTypes[0].newInstance());
        }
        if (!isJson && hasRequestBody) {
            throw new HttpMediaTypeNotSupportedException("Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported");
        }

        // 拿到参数类型  ItemAddDTO
        Class<?> parameterType = parameterTypes[0];
        Object parameter = parameterType.newInstance();
        // 把map里面的数据封装到对象中
        Set<Map.Entry<String, Object>> entries = map.entrySet();
        for (Map.Entry<String, Object> entry : entries) {
            Method declaredMethod = parameterType.getDeclaredMethod(
                    // setName
                    "set" + entry.getKey().substring(0, 1).toUpperCase() + entry.getKey().substring(1),
                    String.class);
            declaredMethod.invoke(parameter, entry.getValue());
        }

        // 最终ItemController返回JsonResult
        return (T) addItem.invoke(cls.newInstance(), parameter);

    }

    public static void main(String[] args) throws Exception {
        String str = "{name:杯子,price:123}";
        //String str = "?name=杯子&price=123";
        JsonResult jsonResult  = parseAndPackage(str, JsonResult.class);
        System.out.println(jsonResult);
    }


}
